/**
 * @file protocol_interface.h
 * @brief 104协议库用户接口头文件
 * @details 声明用户友好的协议接口函数
 * 
 * @author zyb
 * @date 2025-10-19
 * @version 1.0
 */

#ifndef PROTOCOL_INTERFACE_H
#define PROTOCOL_INTERFACE_H

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>
#include <stdbool.h>

/* ==================== 用户接口类型定义 ==================== */

/**
 * @brief 数据类型枚举
 */
typedef enum {
    DATA_TYPE_SINGLE_POINT = 1,      // 单点信息
    DATA_TYPE_DOUBLE_POINT = 3,      // 双点信息
    DATA_TYPE_MEASUREMENT = 9,       // 测量值
    DATA_TYPE_SINGLE_COMMAND = 45,   // 单命令
    DATA_TYPE_DOUBLE_COMMAND = 46,   // 双命令
    DATA_TYPE_CLOCK_SYNC = 103,      // 时钟同步
    DATA_TYPE_INTERROGATION = 100    // 总召唤
} data_type_t;

/**
 * @brief 数据质量枚举
 */
typedef enum {
    DATA_QUALITY_GOOD = 0,
    DATA_QUALITY_UNCERTAIN = 1,
    DATA_QUALITY_BAD = 2,
    DATA_QUALITY_INVALID = 3
} data_quality_t;

/**
 * @brief 发送结果枚举
 */
typedef enum {
    SEND_RESULT_SUCCESS = 0,         // 发送成功
    SEND_RESULT_FAILED = 1,          // 发送失败
    SEND_RESULT_TIMEOUT = 2,         // 发送超时
    SEND_RESULT_DISCONNECTED = 3,    // 连接断开
    SEND_RESULT_INVALID_DATA = 4     // 数据无效
} send_result_t;

/* ==================== 前向声明 ==================== */

typedef struct protocol_handle* protocol_handle_t;
typedef struct protocol_config protocol_config_t;

/* ==================== 数据结构定义 ==================== */

/**
 * @brief 数据点结构
 */
typedef struct data_point {
    uint32_t address;           // 信息对象地址
    data_type_t type;          // 数据类型
    data_quality_t quality;    // 数据质量
    uint64_t timestamp;        // 时间戳（毫秒）
    union {
        bool single_point;     // 单点值
        uint8_t double_point;  // 双点值 (0=中间态, 1=分, 2=合)
        float measurement;     // 测量值
        bool single_command;   // 单命令
        uint8_t double_command; // 双命令
    } value;
} data_point_t;

/**
 * @brief 协议数据类型枚举
 */
typedef enum {
    PROTOCOL_DATA_APDU = 0,        // APDU数据包
    PROTOCOL_DATA_ASDU = 1,        // ASDU数据单元
    PROTOCOL_DATA_TELEMETRY = 2,   // 遥测数据
    PROTOCOL_DATA_CONTROL = 3,     // 控制数据
    PROTOCOL_DATA_HEARTBEAT = 4    // 心跳数据
} protocol_data_type_t;

/**
 * @brief 遥测数据结构
 */
typedef struct {
    uint32_t object_address;       // 对象地址
    uint8_t type_id;              // 类型标识
    uint16_t value;               // 遥测值
    uint8_t quality;              // 质量描述符
    uint32_t timestamp;           // 时间戳
} telemetry_data_t;

/**
 * @brief 控制数据结构
 */
typedef struct {
    uint32_t object_address;       // 对象地址
    uint8_t type_id;              // 类型标识
    uint8_t control_value;        // 控制值
    uint8_t select_execute;       // 选择/执行标志
    uint32_t timestamp;           // 时间戳
} control_data_t;

/**
 * @brief 组装后的数据包结构
 */
typedef struct {
    protocol_data_type_t type;    // 数据类型
    uint32_t length;              // 数据长度
    uint8_t *data;                // 数据内容
    bool ready_to_send;           // 是否准备发送
} assembled_packet_t;

/**
 * @brief 解析后的数据包结构
 */
typedef struct {
    protocol_data_type_t type;    // 数据类型
    uint32_t length;              // 数据长度
    uint8_t *data;                // 数据内容
    uint32_t timestamp;           // 时间戳
    bool valid;                   // 数据有效性
} parsed_data_t;

/* ==================== 协议实例管理函数 ==================== */

/**
 * @brief 创建协议实例
 * @details 根据提供的配置参数创建新的104协议实例
 * 
 * @param config 协议配置参数，不能为NULL
 * @return 协议句柄，失败时返回NULL
 */
protocol_handle_t protocol_create(const protocol_config_t* config);

/**
 * @brief 销毁协议实例
 * @details 释放协议实例占用的所有资源
 * 
 * @param handle 协议句柄，不能为NULL
 */
void protocol_destroy(protocol_handle_t handle);

/**
 * @brief 连接协议
 * @details 建立与远程服务器的连接
 * 
 * @param handle 协议句柄，不能为NULL
 * @return 连接结果
 */
int protocol_connect(protocol_handle_t handle);

/**
 * @brief 断开协议连接
 * @details 断开与远程服务器的连接
 * 
 * @param handle 协议句柄，不能为NULL
 */
void protocol_disconnect(protocol_handle_t handle);

/* ==================== 数据发送函数 ==================== */

/**
 * @brief 发送单点数据
 * @details 发送单点遥信数据
 * 
 * @param handle 协议句柄，不能为NULL
 * @param address 数据地址
 * @param value 数据值
 * @param quality 数据质量
 * @return 发送结果
 */
send_result_t protocol_send_single_point(protocol_handle_t handle, 
                                        uint32_t address, 
                                        bool value, 
                                        data_quality_t quality);

/**
 * @brief 发送双点数据
 * @details 发送双点遥信数据
 * 
 * @param handle 协议句柄，不能为NULL
 * @param address 数据地址
 * @param value 数据值
 * @param quality 数据质量
 * @return 发送结果
 */
send_result_t protocol_send_double_point(protocol_handle_t handle, 
                                        uint32_t address, 
                                        uint8_t value, 
                                        data_quality_t quality);

/**
 * @brief 发送测量值数据
 * @details 发送遥测数据
 * 
 * @param handle 协议句柄，不能为NULL
 * @param address 数据地址
 * @param value 数据值
 * @param quality 数据质量
 * @return 发送结果
 */
send_result_t protocol_send_measurement(protocol_handle_t handle, 
                                       uint32_t address, 
                                       float value, 
                                       data_quality_t quality);

/**
 * @brief 发送控制命令
 * @details 发送遥控命令
 * 
 * @param handle 协议句柄，不能为NULL
 * @param address 控制地址
 * @param command 控制命令
 * @return 发送结果
 */
send_result_t protocol_send_control_command(protocol_handle_t handle, 
                                           uint32_t address, 
                                           uint8_t command);

/* ==================== 数据接收函数 ==================== */

/**
 * @brief 接收数据
 * @details 接收来自远程服务器的数据
 * 
 * @param handle 协议句柄，不能为NULL
 * @param data_points 数据点数组
 * @param max_count 最大数据点数量
 * @param actual_count 实际接收的数据点数量
 * @return 接收结果
 */
int protocol_receive_data(protocol_handle_t handle, 
                         data_point_t* data_points, 
                         int max_count, 
                         int* actual_count);

/**
 * @brief 接收原始数据
 * @details 接收来自网络的原始数据并解析
 * 
 * @param handle 协议句柄，不能为NULL
 * @param raw_data 原始数据缓冲区
 * @param data_length 数据长度
 * @return 解析结果，0表示成功
 */
int protocol_receive_raw_data(protocol_handle_t handle, 
                             const uint8_t* raw_data, 
                             uint32_t data_length);

/**
 * @brief 获取解析后的数据
 * @details 获取最近解析的数据点
 * 
 * @param handle 协议句柄，不能为NULL
 * @param data_points 数据点数组
 * @param max_count 最大数据点数量
 * @param actual_count 实际数据点数量
 * @return 获取结果，0表示成功
 */
int protocol_get_parsed_data(protocol_handle_t handle, 
                            data_point_t* data_points, 
                            int max_count, 
                            int* actual_count);

/* ==================== 状态查询函数 ==================== */

/**
 * @brief 检查连接状态
 * @details 检查协议连接是否正常
 * 
 * @param handle 协议句柄，不能为NULL
 * @return 连接状态，true表示已连接，false表示未连接
 */
bool protocol_is_connected(protocol_handle_t handle);

/**
 * @brief 获取协议版本
 * @details 获取当前协议库的版本信息
 * 
 * @return 版本字符串
 */
const char* protocol_get_version(void);

#ifdef __cplusplus
}
#endif

#endif /* PROTOCOL_INTERFACE_H */
